/*
 * 代号：凤凰
 * http://www.jphenix.org
 * 2014年9月9日
 * V4.0
 */
package com.jphenix.share.tools;

import com.jphenix.driver.nodehandler.FNodeHandler;
import com.jphenix.share.lang.SBoolean;
import com.jphenix.share.lang.SDouble;
import com.jphenix.share.lang.SInteger;
import com.jphenix.share.lang.SLong;
import com.jphenix.share.util.BaseUtil;
import com.jphenix.standard.docs.ClassInfo;
import com.jphenix.standard.viewhandler.INodeHandler;
import com.jphenix.standard.viewhandler.IViewHandler;

import javax.servlet.http.HttpSession;
import java.lang.reflect.Field;
import java.util.*;

/**
 * Servlet工具类
 * 
 * 2019-04-09 用SDouble替代了SFloat
 * 
 * @author 马宝刚
 * 2014年9月9日
 */
@ClassInfo({"2019-04-09 11:23","Servlet工具类"})
public class ServletTools {

    /**
     * 将Session类实例转换成XML格式字符串
     * 
     * 注意：该方法只能转换出以下会话中的对象：
     * 
     * String
     * Map
     * List
     * Bean（类中的变量值）
     * Array
     * 
     * @param session 会话类实例
     * @return XML 格式字符串
     * 2014年9月9日
     * @author 马宝刚
     */
    public static String sessionToXmlString(HttpSession session) {
        if(session==null) {
            return null;
        }
        //会话属性名
        Enumeration<String> names = session.getAttributeNames();
        if(!names.hasMoreElements()) {
            return null;
        }
        //构建返回值
        StringBuffer reSbf = new StringBuffer();
        reSbf.append("<?xml version=\"1.0\" encoding='UTF-8'?>\n<root>");
        if(names!=null) {
            String key; //会话属性主键
            Object value; //会话值
            while(names.hasMoreElements()) {
                key = names.nextElement();
                if(key==null) {
                    continue;
                }
                value = session.getAttribute(key);
                if(value==null) {
                    continue;
                }
                reSbf.append(getObjectString(key,value));
            }
        }
        reSbf.append("</root>");
        return reSbf.toString();
    }
    
    /**
     * 将对象类实例转换为XML格式
     * @param obj 对象类实例
     * @return XML 格式信息
     * 2014年9月9日
     * @author 马宝刚
     */
    @SuppressWarnings("rawtypes")
    private static String getObjectString(String key,Object obj) {
        //构建返回值
        StringBuffer reSbf = new StringBuffer();
        if(obj==null) {
            reSbf.append("<object id=\"").append(key).append("\" type=\"unknown\"></object>");
        }else if(obj instanceof String) {
            reSbf.append("<object id=\"").append(key).append("\" type=\"String\"><![CDATA[").append(obj).append("]]></object>");
        }else if(obj instanceof Integer) {
            reSbf.append("<object id=\"").append(key).append("\" type=\"Integer\">").append(((Integer)obj).intValue()).append("</object>");
        }else if(obj instanceof Long) {
            reSbf.append("<object id=\"").append(key).append("\" type=\"Long\">").append(((Long)obj).longValue()).append("</object>");
        }else if(obj instanceof Double) {
            reSbf.append("<object id=\"").append(key).append("\" type=\"Double\">").append(((Double)obj).doubleValue()).append("</object>");
        }else if(obj instanceof Float) {
            reSbf.append("<object id=\"").append(key).append("\" type=\"Float\">").append(((Float)obj).floatValue()).append("</object>");
        }else if(obj instanceof Boolean) {
            reSbf.append("<object id=\"").append(key).append("\" type=\"Boolean\">").append(((Boolean)obj).booleanValue()).append("</object>");
        }else if(obj instanceof String[]) {
            reSbf.append("<object id=\"").append(key).append("\" type=\"String\" is_array=\"1\">");
            String[] valArrs = (String[])obj; //强制转换后的值
            for(String ele:valArrs) {
                   reSbf.append("<ele><![CDATA[").append(ele).append("]]></ele>\n");
            }
            reSbf.append("</object>");
        }else if(obj instanceof int[]) {
            reSbf.append("<object id=\"").append(key).append("\" type=\"int\" is_array=\"1\">");
            int[] valArrs = (int[])obj; //强制转换后的值
            for(int ele:valArrs) {
                   reSbf.append("<ele><![CDATA[").append(ele).append("]]></ele>\n");
            }
            reSbf.append("</object>");
        }else if(obj instanceof long[]) {
            reSbf.append("<object id=\"").append(key).append("\" type=\"long\" is_array=\"1\">");
            long[] valArrs = (long[])obj; //强制转换后的值
            for(long ele:valArrs) {
                   reSbf.append("<ele><![CDATA[").append(ele).append("]]></ele>\n");
            }
            reSbf.append("</object>");
        }else if(obj instanceof double[]) {
            reSbf.append("<object id=\"").append(key).append("\" type=\"double\" is_array=\"1\">");
            double[] valArrs = (double[])obj; //强制转换后的值
            for(double ele:valArrs) {
                   reSbf.append("<ele><![CDATA[").append(ele).append("]]></ele>\n");
            }
            reSbf.append("</object>");
        }else if(obj instanceof float[]) {
            reSbf.append("<object id=\"").append(key).append("\" type=\"float\" is_array=\"1\">");
            float[] valArrs = (float[])obj; //强制转换后的值
            for(float ele:valArrs) {
                   reSbf.append("<ele><![CDATA[").append(ele).append("]]></ele>\n");
            }
            reSbf.append("</object>");
        }else if(obj instanceof boolean[]) {
            reSbf.append("<object id=\"").append(key).append("\" type=\"boolean\" is_array=\"1\">");
            boolean[] valArrs = (boolean[])obj; //强制转换后的值
            for(boolean ele:valArrs) {
                   reSbf.append("<ele><![CDATA[").append(ele).append("]]></ele>\n");
            }
            reSbf.append("</object>");
        }else if(obj instanceof Map) {
            reSbf.append("<object id=\"").append(key).append("\" type=\"Map\">");
            Map val = (Map)obj; //强制转换后的值
            List<String> keyList = BaseUtil.getMapKeyList(val);
            for(String ele:keyList) {
                   reSbf.append(getObjectString(ele,val.get(ele)));
            }
            reSbf.append("</object>");
        }else if(obj instanceof List) {
            reSbf.append("<object id=\"").append(key).append("\" type=\"List\">");
            List val = (List)obj; //强制转换后的值
            for(Object ele:val) {
                   reSbf.append(getObjectString("",ele));
            }
            reSbf.append("</object>");
        }else {
            reSbf.append("<object id=\"").append(key).append("\" type=\"").append(obj.getClass().getName()).append("\">");
            //获取类变量数组
            Field[] fields = obj.getClass().getFields();
            Object value; //字段值
            for(Field field:fields) {
                try {
                    field.setAccessible(true);
                    value = field.get(obj);
                    if(value!=null) {
                        reSbf.append(getObjectString(field.getName(),value));
                    }
                }catch(Exception e) {}
            }
            reSbf.append("</object>");
        }
        return reSbf.append("\n").toString();
    }
    
    /**
     * 将XML格式字符串解析后设置到当前会话中
     * @param session 当前会话
     * @param xml XML格式字符串（会话中的对象值）
     * @throws Exception 异常
     * 2014年9月9日
     * @author 马宝刚
     */
    public static void setSessionFromXmlString(HttpSession session,String xml) throws Exception {
        if(session==null || xml==null || xml.length()<1) {
            return;
        }
        //构建xml解析类
        INodeHandler nh = FNodeHandler.newNodeHandler();
        nh.setXmlStyle(true);
        nh.setNodeBody(xml); //设置内容
        
        //获取子节点序列
        List<IViewHandler> childList = nh.getFirstChildNodeByNodeName("root").getChildDealNodes();
        Object obj; //对应的值
        for(IViewHandler child:childList) {
            if(!"object".equals(child.nn())) {
                continue;
            }
            obj = getObject(child);
            if(obj!=null) {
                session.setAttribute(child.a("id"),obj);
            }
        }
    }
    
    
    /**
     * 将xml格式内容转换为对象实例
     * @param nh xml对象
     * @return 对应的对象实例
     * @throws Exception 异常
     * 2014年9月9日
     * @author 马宝刚
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    private static Object getObject(IViewHandler nh) throws Exception {
        String type = nh.a("type"); //对象类型
        if("unknown".equals(type)) {
            return null;
        }
        boolean isArray = SBoolean.valueOf(nh.a("is_array")); //参数是否为数组
        if(isArray) {
            //信息子节点序列
            List<IViewHandler> eleList = nh.getChildNodesByNodeName("ele");
            
            if("String".equals(type)) {
                //构建返回值
                String[] val = new String[eleList.size()];
                IViewHandler ele; //元素
                for(int i=0;i<eleList.size();i++) {
                    ele = eleList.get(i);
                    val[i] = ele.nt();
                }
                return val;
            }else if("int".equals(type)) {
                //构建返回值
                int[] val = new int[eleList.size()];
                IViewHandler ele; //元素
                for(int i=0;i<eleList.size();i++) {
                    ele = eleList.get(i);
                    val[i] = SInteger.valueOf(ele.nt());
                }
                return val;
            }else if("long".equals(type)) {
                //构建返回值
                long[] val = new long[eleList.size()];
                IViewHandler ele; //元素
                for(int i=0;i<eleList.size();i++) {
                    ele = eleList.get(i);
                    val[i] = SLong.valueOf(ele.nt());
                }
                return val;
            }else if("double".equals(type)) {
                //构建返回值
                double[] val = new double[eleList.size()];
                IViewHandler ele; //元素
                for(int i=0;i<eleList.size();i++) {
                    ele = eleList.get(i);
                    val[i] = SDouble.valueOf(ele.nt());
                }
                return val;
            }else if("float".equals(type)) {
                //构建返回值
                float[] val = new float[eleList.size()];
                IViewHandler ele; //元素
                for(int i=0;i<eleList.size();i++) {
                    ele = eleList.get(i);
                    val[i] = (float)SDouble.valueOf(ele.nt());
                }
                return val;
            }else if("boolean".equals(type)) {
                //构建返回值
                boolean[] val = new boolean[eleList.size()];
                IViewHandler ele; //元素
                for(int i=0;i<eleList.size();i++) {
                    ele = eleList.get(i);
                    val[i] = SBoolean.valueOf(ele.nt());
                }
                return val;
            }
        }else {
            if("String".equals(type)) {
                return nh.nt();
            }else if("Integer".equals(type)) {
                return SInteger.integerOf(nh.nt());
            }else if("Long".equals(type)) {
                return SLong.longOf(nh.nt());
            }else if("Double".equals(type)) {
                return SDouble.doubleOf(nh.nt());
            }else if("Float".equals(type)) {
                return SDouble.doubleOf(nh.nt());
            }else if("Boolean".equals(type)) {
                return SBoolean.booleanOf(nh.nt());
            }else if("Map".equals(type)) {
                //构建返回值
                HashMap reMap = new HashMap();
                //获取子元素序列
                List<IViewHandler> childList = nh.getChildDealNodes();
                String key; //主键
                for(IViewHandler child:childList) {
                    if(!"object".equals(child.nn())) {
                        continue;
                    }
                    key = child.a("id");
                    if(key.length()<1) {
                        continue;
                    }
                    reMap.put(key,getObject(child));
                }
                return reMap;
            }else if("List".equals(type)) {
                //构建返回值 
                ArrayList reList = new ArrayList();
                //获取子元素序列
                List<IViewHandler> childList = nh.getChildDealNodes();
                for(IViewHandler child:childList) {
                    if(!"object".equals(child.nn())) {
                        continue;
                    }
                    reList.add(getObject(child));
                }
                return reList;
            }else {
                //构建返回值类型
                Class reCls = Class.forName(type);
                //构建返回值
                Object reObj = reCls.newInstance();
                //获取子元素序列
                List<IViewHandler> childList = nh.getChildDealNodes();
                String key; //主键
                Field field; //变量元素
                for(IViewHandler child:childList) {
                    if(!"object".equals(child.nn())) {
                        continue;
                    }
                    key = child.a("id");
                    if(key.length()<1) {
                        continue;
                    }
                    try {
                        field = reCls.getField(key);
                        if(field==null) {
                            continue;
                        }
                        field.setAccessible(true);
                        field.set(reObj,getObject(child));
                    }catch(Exception e) {
                        e.printStackTrace();
                    }
                }
                return reObj;
            }
        }
        return null;
    }
}
